import axios from 'axios'
import { ElMessage } from 'element-plus'

// 创建axios实例
const service = axios.create({
  baseURL: '', // 使用相对路径，由Vite代理处理
  timeout: 30000  // 增加超时时间到30秒
})

// request拦截器
service.interceptors.request.use(
  config => {
    console.log('请求开始 ->', config.method.toUpperCase(), config.url);
    
    // 检查本地存储中是否有token
    const token = localStorage.getItem('token')
    
    // 添加日志记录请求信息
    if (config.params) {
      console.log('请求参数(params):', Object.keys(config.params).join(', '));
    }
    
    if (config.data) {
      console.log('请求数据(body):', typeof config.data === 'object' ? Object.keys(config.data).join(', ') : '非对象数据');
    }
    
    // 存在token且token内容有效（简单验证）
    if (token && /^[A-Za-z0-9-_=]+\.[A-Za-z0-9-_=]+\.[A-Za-z0-9-_.+/=]*$/.test(token)) {
      // 检查令牌是否已过期（通过解析JWT的payload部分）
      try {
        const base64Url = token.split('.')[1];
        const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
        const payload = JSON.parse(window.atob(base64));
        const expiresAt = payload.exp * 1000; // 转换为毫秒
        
        if (Date.now() >= expiresAt) {
          console.warn('令牌已过期! 过期时间:', new Date(expiresAt).toLocaleString());
          // 可以在这里增加自动跳转到登录页或弹出提示
        } else {
          // 计算剩余时间
          const remainingTime = Math.round((expiresAt - Date.now()) / 1000 / 60); // 分钟
          console.log(`令牌有效，剩余 ${remainingTime} 分钟`);
        }
      } catch (e) {
        console.warn('无法解析令牌:', e.message);
      }
      
      // 设置统一的token到header中
      config.headers['Authorization'] = 'Bearer ' + token
      console.log('已添加令牌到请求头');
    } else {
      // 检查路径是否需要认证
      if (isAuthRequiredPath(config.url, config.method)) {
        console.warn('警告: 此请求需要认证，但未提供有效令牌!', config.url);
      } else {
        console.log('此路径无需认证');
      }
    }
    
    return config
  },
  error => {
    console.error('请求拦截器错误:', error)
    return Promise.reject(error)
  }
)

/**
 * 判断是否是需要认证的路径
 */
function isAuthRequiredPath(url, method) {
  // 默认所有非GET请求都需要认证
  if (method && method.toLowerCase() !== 'get') {
    // 例外：部分POST请求不需要认证，如登录接口
    if (url.includes('/api/auth/login') || 
        url.includes('/api/register') || 
        url.includes('/api/verify')) {
      return false;
    }
    return true;
  }
  
  // 公开的GET端点列表
  const publicGetPaths = [
    '/api/auth/',
    '/api/public/',
    '/api/options/',
    '/api/categories'
  ];
  
  // 检查是否为公开路径
  for (const publicPath of publicGetPaths) {
    if (url.includes(publicPath)) {
      return false;
    }
  }
  
  // 默认用户相关和任务相关API需要认证
  if (url.includes('/api/users') || 
      url.includes('/api/tasks') || 
      url.includes('/api/profile') ||
      url.includes('/api/company') ||
      url.includes('/api/worker') ||
      url.includes('/api/admin')) {
    return true;
  }
  
  // 默认不需要认证
  return false;
}

// response拦截器
service.interceptors.response.use(
  response => {
    console.log('响应状态:', response.status, response.statusText);
    
    // 记录响应头信息，用于调试
    const headers = response.headers;
    console.log('响应头:', {
      'content-type': headers['content-type'],
      'content-length': headers['content-length']
    });
    
    // 检查响应内容类型是否为JSON
    const contentType = headers['content-type'] || '';
    const isJson = contentType.includes('application/json');
    console.log('响应类型是否为JSON:', isJson);
    
    // 保存原始响应数据，以便稍后查看
    const originalData = response.data;
    
    // 如果内容类型声明为JSON但实际不是对象，尝试解析
    if (isJson && typeof originalData === 'string') {
      console.warn('响应声明为JSON但返回了字符串，尝试解析');
      try {
        response.data = JSON.parse(originalData);
        console.log('成功解析JSON字符串:', response.data);
      } catch (error) {
        console.error('JSON解析错误:', error.message);
        console.error('原始数据:', originalData);
        // 保留原始数据，继续处理
      }
    }
    
    // 详细记录响应数据类型和结构
    const respData = response.data;
    console.log('响应数据类型:', typeof respData, Array.isArray(respData) ? '是数组' : '非数组');
    if (typeof respData === 'object' && respData !== null) {
      console.log('响应数据字段:', Object.keys(respData).join(', '));
      
      // 检查是否有嵌套的data字段
      if (respData.data !== undefined) {
        console.log('data字段类型:', typeof respData.data, 
                    Array.isArray(respData.data) ? `数组[${respData.data.length}]` : '非数组');
      }
    }
    
    // 检查响应状态码是否为成功
    const statusCode = response.status;
    if (statusCode < 200 || statusCode >= 300) {
      console.warn('HTTP状态码非2xx范围:', statusCode);
      return Promise.reject(new Error('HTTP状态码非2xx: ' + statusCode));
    }
    
    // 如果响应是空的，但HTTP状态成功
    if (!respData && statusCode >= 200 && statusCode < 300) {
      console.warn('成功响应，但无数据');
      return {
        code: 200,
        success: true,
        message: '成功，但服务器未返回数据',
        data: null,
        _originalResponse: originalData  // 保存原始响应
      };
    }
    
    // 标准API响应格式检查
    if (typeof respData === 'object' && !Array.isArray(respData)) {
      if (respData.code !== undefined) {
        // 处理具有code字段的标准响应
        console.log('标准响应格式，状态码:', respData.code);
        
        // 如果是错误代码
        if (respData.code !== 200 && respData.code !== 0) {
          console.warn('API响应错误码:', respData.code, '消息:', respData.message);
          
          // 处理常见的API错误代码
          if (respData.code === 401) {
            console.error('身份验证失败，需要重新登录');
            // 可以在这里处理自动跳转到登录页面
          } else if (respData.code === 403) {
            console.error('无权访问请求的资源');
          }
          
          // 返回原始响应，让业务层处理
          return {
            ...respData,
            _originalResponse: originalData  // 保存原始响应
          };
        }
        
        // 成功响应的数据规范化
        return {
          ...respData,
          _originalResponse: originalData  // 保存原始响应
        };
      }
      
      // 非标准格式，但包含success/status/ok等标准字段
      if ('success' in respData || 'status' in respData || 'ok' in respData) {
        // 判断响应是否包含直接数据(如包含id、title等属性的任务对象)
        // 如果是一个包含id和其他业务属性的对象，不应该被当作API状态处理
        const isDataObject = respData.id !== undefined && 
                            (respData.title !== undefined || 
                             respData.companyId !== undefined || 
                             respData.status !== undefined);
        
        if (isDataObject) {
          console.log('响应包含直接数据对象，跳过状态判断');
          // 直接返回数据对象
          return respData;
        }
        
        const isSuccess = respData.success === true || respData.status === 'success' || respData.ok === true;
        console.log('非标准格式响应，成功状态:', isSuccess);
        
        if (!isSuccess) {
          console.warn('API响应指示失败:', respData);
          return {
            code: 500,
            success: false,
            message: respData.message || respData.error || '服务器处理失败',
            data: null,
            originalResponse: respData,
            _originalResponse: originalData  // 保存原始响应
          };
        }
      }
    }
    
    // 如果响应是数组，将其包装为标准格式
    if (Array.isArray(respData)) {
      console.log('响应是数组，长度:', respData.length);
      return {
        code: 200,
        success: true,
        message: '成功',
        data: respData,
        _originalResponse: originalData  // 保存原始响应
      };
    }
    
    // 默认返回响应数据，无论什么格式，都添加原始数据属性
    if (typeof respData === 'object' && respData !== null) {
      return {
        ...respData,
        _originalResponse: originalData  // 保存原始响应
      };
    }
    
    // 处理非对象类型的返回值
    return {
      code: 200,
      success: true,
      data: respData,
      _originalResponse: originalData  // 保存原始响应
    };
  },
  error => {
    console.error('请求出错:', error.name, error.message);
    
    // 打印错误的请求配置，帮助诊断问题
    if (error.config) {
      console.error('出错的请求配置:', {
        url: error.config.url,
        method: error.config.method,
        headers: error.config.headers,
        timeout: error.config.timeout
      });
    }
    
    // 格式化错误消息并增加可读性
    let errorMessage = '请求失败';
    let originalResponse = null;
    
    if (error.response) {
      // 保存原始响应
      if (error.response.data) {
        originalResponse = error.response.data;
      }
      
      // 服务器响应了，但状态码超出2xx范围
      const status = error.response.status;
      console.error('HTTP错误状态码:', status);
      
      // 为常见HTTP错误代码提供更友好的消息
      switch (status) {
        case 400:
          errorMessage = '请求参数错误';
          break;
        case 401:
          errorMessage = '身份验证失败，请重新登录';
          break;
        case 403:
          errorMessage = '无权限执行此操作';
          break;
        case 404:
          errorMessage = '请求的资源不存在';
          break;
        case 422:
          errorMessage = '请求参数验证失败';
          break;
        case 500:
          errorMessage = '服务器内部错误';
          break;
        case 502:
          errorMessage = '网关错误';
          break;
        case 503:
          errorMessage = '服务暂时不可用';
          break;
        case 504:
          errorMessage = '网关超时';
          break;
        default:
          errorMessage = `服务器响应错误 (${status})`;
      }
      
      // 如果响应中包含错误信息，使用它
      if (error.response.data) {
        if (typeof error.response.data === 'string') {
          errorMessage += ': ' + error.response.data;
        } else if (error.response.data.message) {
          errorMessage += ': ' + error.response.data.message;
        } else if (error.response.data.error) {
          errorMessage += ': ' + error.response.data.error;
        }
      }
    } else if (error.request) {
      // 请求已发送但未收到响应
      console.error('没有收到响应:', error.request);
      
      if (error.code === 'ECONNABORTED') {
        errorMessage = '请求超时，请检查网络连接';
      } else {
        errorMessage = '未收到服务器响应，请检查网络连接';
      }
    } else {
      // 发送请求时出错
      console.error('请求配置错误:', error.message);
      errorMessage = '请求配置错误: ' + error.message;
    }
    
    // 返回格式化的错误对象，包括原始响应
    return Promise.reject({
      success: false,
      code: error.response ? error.response.status : 500,
      message: errorMessage,
      error: error,
      _originalResponse: originalResponse  // 保存原始响应，方便调试
    });
  }
)

/**
 * 统一处理token过期
 */
function handleTokenExpired(message) {
  ElMessage({
    message: message,
    type: 'error',
    duration: 3000,
    showClose: true,
    onClose: () => {
      // 清除token等信息
      localStorage.removeItem('token')
      localStorage.removeItem('userType')
      localStorage.removeItem('username')
      // 跳转到登录页
      if (location.pathname !== '/login') {
        location.href = '/login'
      }
    }
  })
}

export default service 